// 输入框验证规则
interface IRole {
  require?: boolean;
  length?: number;
  max?: number;
  min?: number;
  key?: string;
  message?: string;
  type?: string;
  trigger?: "change" | "blur";
  validator?: Function;
}
interface IOperateGroup {
  name: string;
  type?: string;
  value?: number | "";
  rules?: Array<IRole>;
  event: IBinarySearchTreeMethodsLiteral;
  params: "Fn" | "val";
}

// 二叉搜索数节点
interface INode {
  id: number;
  parent: any;
  parentId: number;
  level: number;
  $el: any;
  left: any;
  key: number;
  right: any;
  isLeft: boolean,
  offset: number;
  top: number;
  isRoot: boolean;
  leftLine: number;
  rightLine: number;
  leftAngle: number;
  rightAngle: number;
  relationLeft?: boolean;
}

// 二叉搜索树的方法们
interface IBinarySearchTreeMethods extends INode {
  insert: IBinarySearchTreeInsert;
  remove: IBinarySearchTreeMethod;
  search: IBinarySearchTreeMethod;
  min: IBinarySearchTreeOtherMethod;
  max: IBinarySearchTreeOtherMethod;
  mostValue: IBinarySearchTreeExpandMethods;
  orderTraversal: IBinarySearchTreeExpandMethods;
  preOrderTraversal: IBinarySearchTreeOtherMethod;
  midOrderTraversal: IBinarySearchTreeOtherMethod;
  postOrderTraversal: IBinarySearchTreeOtherMethod;
  clear: () => void;
  getSiblingNodes: (node: INode) => Array<INode> | null;
  getRoot: () => INode | null;
  getChildrenFlag: (node: INode, parent?: INode) => string;
  getParentEqual: (node: INode, refer: INode) => INode | null;
  generateBST: () => void;
  exportBST: () => void;
  searchGrandpaNode: (node: INode) => INode;
}

// 二叉搜索树类型
interface IBinarySearchTree extends IBinarySearchTreeMethods {
  root: IBinarySearchTree;
  left: IBinarySearchTree;
  key: number;
  right: IBinarySearchTree;
  id: number;
  offset: number;
  isLeft: boolean;
  isRoot: boolean;
  top: number;
  min: IBinarySearchTreeMostValueMethod;
  max: IBinarySearchTreeMostValueMethod;
}

// 优先级队列类型
interface IPriorityQueue {
  items: Array<any>;
  enqueue: (element: any, priority: number) => void;
  dequeue: () => IPQElement;
  front: () => IPQElement;
  isEmpty: () => boolean;
  size: () => number;
  toString: () => string;
  clear: () => void;
}

// 优先级队列元素类型
interface IPQElement {
  element: any;
  priority: number;
}

declare type IBinarySearchTreeKey = number;
// 二叉搜索树插入方法
declare type IBinarySearchTreeInsert = (value: IBinarySearchTreeKey, handler?: IInsertCallback) => void;
// 二叉搜索树删改查方法
declare type IBinarySearchTreeMethod = (value: IBinarySearchTreeKey, handler?: ITraversalCallBack) => void;
// 二叉搜索树其他方法
declare type IBinarySearchTreeOtherMethod = (callback?: ITraversalCallBack) => void;
// 获取最大最小值的方法
declare type IBinarySearchTreeMostValueMethod = (callback?: ITraversalCallBack) => number & string;

// 二叉搜索树扩展方法
declare type IBinarySearchTreeExpandMethods = (method: string, control: string, args?: Array<any>) => void;

// 二叉搜索树方法字面量
declare type IBinarySearchTreeMethodsLiteral = "insert" | "remove" | "search" | "min" | "max" | "preOrderTraversal" | "midOrderTraversal" | "postOrderTraversal" | "clear" | "generateBST" | "exportBST";

// 递归子项
declare interface IRecursionItem {
  name: string;
  children: Array<IRecursionItem>
}

// 导航栏子项
interface INavigationItem {
  icon: string;
  title: string;
  name: string;
  children: Array<INavigationItem>;
}

// 遍历的回调
declare type ITraversalCallBack = (key: IBinarySearchTreeKey) => void;

interface IComponentInfo {
  component: any;
  node: any
}

declare type IInsertCallback = (node: IBinarySearchTree | INode | null, key?: string) => INode;

// 基础配置属性
interface IBaseConfig {
  levelInterval: number
}

// 基础配置字面量
declare type IBaseConfigLiteral = "levelInterval"

interface IVStyle {
  height: string;
  width: string;
  border: string;
  margin: string;
  padding: string;
  display: string;
  overflow: string;
  top: string;
  left: string;
  right: string;
  bottom: string;
}

interface IVElement extends ParentNode {
  style: IVStyle;
}

interface IVEvent {

}

interface IHTMLElm extends HTMLElement {}

interface IElm extends Element {
  dataset: any;
}

interface IMetaOptions {
  title: string;
  name: string;
  path: string;
}

export {
  IRole,
  IOperateGroup,
  IBinarySearchTree,
  IBinarySearchTreeKey,
  IBinarySearchTreeMethods,
  IBinarySearchTreeMethodsLiteral,
  IRecursionItem,
  INavigationItem,
  ITraversalCallBack,
  IPQElement,
  IPriorityQueue,
  IComponentInfo,
  IInsertCallback,
  INode,
  IBaseConfig,
  IBaseConfigLiteral,
  IVElement,
  IVEvent,
  IHTMLElm,
  IElm,
  IMetaOptions
}
